package com.mlethe.library.fingerprint;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.DrawableCompat;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;

import com.mlethe.library.fingerprint.entity.VerificationDialogStyle;

import java.lang.reflect.Field;

/**
 * @author Mlethe
 * @date 2021/6/16
 */
public class FingerprintDialog extends DialogFragment {

    private static final String SAVED_DIALOG_STATE_TAG = "android:savedDialogState";

    /**
     * 弹框关闭监听
     */
    private DialogInterface.OnDismissListener mOnDismissListener;

    private VerificationDialogStyle dialogStyle;

    protected TextView tvTip;

    /**
     * 重置文字状态
     */
    protected Runnable mRestRunnable = new Runnable() {
        @Override
        public void run() {
            if (tvTip != null) {
                tvTip.setText(R.string.biometricprompt_verify_fingerprint);
                tvTip.setTextColor(Color.BLACK);
            }
        }
    };

    /**
     * 错误显示弹窗消失
     */
    private final Runnable mDismissRunnable = new Runnable() {
        @Override
        public void run() {
            dismissAllowingStateLoss();
            if (mRunnable != null) {
                mRunnable.run();
            }
        }
    };

    private Runnable mRunnable;

    @Override
    public final void onActivityCreated(@Nullable Bundle savedInstanceState) {
        boolean showsDialog = getShowsDialog();
        setShowsDialog(false);
        super.onActivityCreated(savedInstanceState);
        setShowsDialog(showsDialog);
        Dialog dialog = getDialog();
        if (dialog == null) {
            return;
        }
        dialog.requestWindowFeature(STYLE_NO_TITLE);
        View view = getView();
        if (view != null) {
            if (view.getParent() != null) {
                throw new IllegalStateException(
                        "DialogFragment can not be attached to a container view");
            }
            dialog.setContentView(view);
        }
        final Activity activity = getActivity();
        if (activity != null) {
            dialog.setOwnerActivity(activity);
        }
        dialog.setCancelable(false);
        dialog.setOnKeyListener((dialog1, keyCode, event) -> {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                dismissAllowingStateLoss();
                return true;
            }
            return false;
        });
        if (savedInstanceState != null) {
            Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
            if (dialogState != null) {
                dialog.onRestoreInstanceState(dialogState);
            }
        }
        Window window = dialog.getWindow();
        if (window == null) {
            return;
        }
        window.getDecorView().setOnTouchListener((v, event) -> true);
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.biometricprompt_layout_fingerprint_dialog, container, false);
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        tvTip = view.findViewById(R.id.tvTip);
        ImageView ivFingerprint = view.findViewById(R.id.ivFingerprint);
        TextView tvCancel = view.findViewById(R.id.tvCancel);
        tvCancel.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dismissAllowingStateLoss();
            }
        });
        // 调用者定义验证框样式
        if (dialogStyle == null) {
            return;
        }
        int cancelTextColor = dialogStyle.getCancelTextColor();
        if (cancelTextColor != 0) {
            tvCancel.setTextColor(cancelTextColor);
        }
        int fingerprintColor = dialogStyle.getFingerprintColor();
        if (fingerprintColor != 0) {
            Drawable wrappedDrawable = DrawableCompat.wrap(ivFingerprint.getDrawable());
            DrawableCompat.setTintList(wrappedDrawable, ColorStateList.valueOf(fingerprintColor));
            ivFingerprint.setImageDrawable(wrappedDrawable);
        }
        String cancelBtnText = dialogStyle.getCancelBtnText();
        if (!TextUtils.isEmpty(cancelBtnText)) {
            tvCancel.setText(cancelBtnText);
        }
    }

    @Override
    public void onDismiss(@NonNull DialogInterface dialog) {
        super.onDismiss(dialog);
        if (mOnDismissListener != null) {
            mOnDismissListener.onDismiss(dialog);
            mOnDismissListener = null;
        }
        dialogStyle = null;
        tvTip = null;
        mRunnable = null;
    }

    /**
     * 显示弹窗
     *
     * @param manager
     * @param tag
     */
    public final void showAllowingStateLoss(FragmentManager manager, String tag) {
        try {
            Class<?> clazz = Class.forName("androidx.fragment.app.DialogFragment");
            Field dismissedField = clazz.getDeclaredField("mDismissed");
            dismissedField.setAccessible(true);
            dismissedField.set(this, false);
            Field shownByMeField = clazz.getDeclaredField("mShownByMe");
            shownByMeField.setAccessible(true);
            shownByMeField.set(this, true);
            manager.beginTransaction()
                    .add(this, tag)
                    .commitNowAllowingStateLoss();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 显示弹窗
     *
     * @param manager
     */
    public final void showAllowingStateLoss(FragmentManager manager) {
        showAllowingStateLoss(manager, getClass().getSimpleName());
    }

    /**
     * dialog Dismiss监听
     * Sets the callback that will be called when the dialog is dismissed for any reason.
     *
     * @return This Builder object to allow for chaining of calls to set methods
     */
    public final FingerprintDialog setOnDismissListener(DialogInterface.OnDismissListener listener) {
        mOnDismissListener = listener;
        return this;
    }

    /**
     * 设置样式
     *
     * @param dialogStyle
     * @return
     */
    public final FingerprintDialog setDialogStyle(VerificationDialogStyle dialogStyle) {
        this.dialogStyle = dialogStyle;
        return this;
    }

    /**
     * 显示失败信息
     *
     * @param str
     * @param color
     */
    public final void showFail(String str, String color) {
        if (tvTip != null) {
            tvTip.setText(str);
            tvTip.setTextColor(Color.parseColor(color));
        }
        View view = getView();
        if (view != null) {
            view.removeCallbacks(mRestRunnable);
            view.postDelayed(mRestRunnable, 2000L);
        }
    }

    /**
     * 显示错误信息
     *
     * @param str
     * @param color
     * @param runnable
     */
    public final void showError(String str, String color, Runnable runnable) {
        if (tvTip != null) {
            tvTip.setText(str);
            tvTip.setTextColor(Color.parseColor(color));
        }
        this.mRunnable = runnable;
        View view = getView();
        if (view != null) {
            view.removeCallbacks(mRestRunnable);
            view.removeCallbacks(mDismissRunnable);
            view.postDelayed(mDismissRunnable, 2500L);
        }
    }
}
